﻿using AutoMapper;
using Domain.User;
using Infratructure;
using Infratructure.Interface;
using MD5Hash;
using MediatR;
using MES.Server.API.Application.Command.Account;
using MES.Server.API.Dto;
using MES.Server.API.Dto.Account;
using Microsoft.IdentityModel.Tokens;
using NPOI.SS.Formula.Functions;
using ReturnValue;
using SixLabors.ImageSharp;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace MES.Server.API.Application.Handler.Account
{
    /// <summary>
    /// 实现用户登录
    /// </summary>
    public class LoginHandler : IRequestHandler<LoginCommand, ApiResult<LoginDTO>>
    {
        private readonly IRepository<AccountModel> accountway;
        private readonly IRepository<AccountRoleModel> accountroleway;
        private readonly IRepository<RoleModel> roleway;
        private readonly ILogger<LoginHandler> log;
        private readonly IMapper mapper;
        private readonly IConfiguration configuration;
   
        public LoginHandler(IRepository<AccountModel> accountway, IRepository<AccountRoleModel>
            accountroleway, IRepository<RoleModel> roleway, ILogger<LoginHandler> log, IMapper mapper, IConfiguration configuration)
        {
            this.accountway = accountway;
            this.accountroleway = accountroleway;
            this.roleway = roleway;
            this.log = log;
            this.mapper = mapper;
            this.configuration = configuration;    
        }
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="request">参数</param>
        /// <param name="cancellationToken">取消</param>
        /// <returns>用户信息</returns>
        public Task<ApiResult<LoginDTO>> Handle(LoginCommand request, CancellationToken cancellationToken)
        {
            ApiResult<LoginDTO> res = new ApiResult<LoginDTO>();
            var account = accountway.GetAll().FirstOrDefault(x => x.AccountName == request.AccountName&&x.IsDel==false);
            if (account != null)
            {
                if (account.AccountPwd == request.AccountPwd.GetMD5())
                {
                    var accountrole = accountroleway.GetAll().FirstOrDefault(x => x.AccountId == account.Id);
                    var rolename = roleway.GetAll().FirstOrDefault(x => x.Id == accountrole.RoleId).RoleName;
                    if (string.IsNullOrEmpty(rolename))
                    {
                        //  log.LogError($"用户未分配角色");
                        res.Fail("用户未分配角色");
                        return Task.FromResult(res);
                    }
                    var dto = new LoginDTO()
                    {
                        AccountName = account.AccountName,
                        RealName = account.RealName,
                        RoleNmae = rolename,
                        Tokenstr = CreateTokenString(account.AccountName, account.RealName, rolename)
                    };                   
                    log.LogInformation($"{DateTime.Now}用户{request.AccountName}登录成功");
                    res.Data = dto;
                    res.Message = $"{DateTime.Now}用户{request.AccountName}登录成功";
                    res.Code = StatusCode.Success;
              
                    return Task.FromResult(res);
                }
                else
                {
                    //密码错误
                    res.Message = $"密码错误,请重试";
                    res.Code = StatusCode.Fail;

                    return Task.FromResult(res);
                }               
            }
            else
            {
                //用户不存在
                //密码错误
                res.Message = $"用户名不存在";
                res.Code = StatusCode.Fail;
                return Task.FromResult(res);
            }
        }
        /// <summary>/// 生成 JWT Token（令牌）/// </summary>/// <returns></returns>
        private string CreateTokenString(string AccountName, string RealName, string RoleNmae)
        {


            var k = configuration["privateKey"];

            //私钥
            var secretByte = Encoding.UTF8.GetBytes(k);
            // 非对称加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            var clamis = new[]
            {
                new Claim("AccountName",AccountName),  //账号
                new Claim("RealName",RealName),       //真实姓名
                new Claim("RoleNmae",RoleNmae),   //角色名称

            };
            // 使用256 生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            // 生成Token
            var token = new JwtSecurityToken(
                issuer: configuration["Issuer"],
                audience: configuration["Audience"],
                expires: DateTime.Now.AddDays(1), // 一天后过期
                signingCredentials: signingCredentials,
                claims: clamis  //载荷
            );
            // 生成token 字符串
            var strToken = new JwtSecurityTokenHandler().WriteToken(token);
            return strToken;
        }
    }
}
